Chapter 16 EXAMPLE PROGRAMS WHY IS THIS CHAPTER INCLUDED? _________________________________________________________________ It would be a real disservice to you to discuss all of the constructs available with Ada, then simply drop you in the middle of a large program and tell you to put it all together. This chapter is intended to illustrate to you, with simple examples, how to put some of these topics together to build a meaningful program. The examples are larger than any programs we have examined to this point, but they are still very simple, and should be easy for you to follow along and understand what they are doing. THE CHARACTER STACK _________________________________________________________________ The program named CHARSTAK.ADA illustrates how ================ you can define your own stack for use in your CHARSTAK.ADA programs. A stack is a list of homogeneous ================ items that grows and shrinks in such a way that the last item entered will always be the first removed, thus it is often referred to as a Last In, First Out (LIFO) list. In order to keep it simple, we will only allow the stack to store CHARACTER type variables, although it could be defined to store any type of variables we desired, even arrays or records. THE SPECIFICATION PACKAGE _________________________________________________________________ The specification package is defined in lines 2 through 20, and gives the user everything he needs to know to use the character stack package. You will see that the user does not know how the stack is implemented, or even how big the stack can grow to unless he looks into the package body, and if we hide the body from him, he has no way of knowing this information. All he can do is use the package the way we tell him it works. In a real system, we would have to tell him how big the stack could grow, because that would probably be valuable information for him when he designed his software, but for our purposes we are not going to let him know the maximum size. Of course, we must then provide a means to be sure that he cannot force the stack to get larger than its maximum size. The procedure Push is defined in such a way that if the stack is full and the character will not fit, it is simply not put on the list. The user must check if the stack is full by calling the function Is_Full which returns a BOOLEAN value of TRUE if there is no additional room on the stack. Page 16-1 Chapter 16 - Example Programs Careful study of the package specification will reveal that enough functions and procedures are included to allow effective use of the character stack. The package body simply defines the actual implementation required to do the work defined in the specification. Once again, you should be able to understand the package body since there is nothing here which is new or strange to you. It should be pointed out to you that this is actually not a very efficient way to define a stack, because it is limited to a single type, but it serves our purposes well as an illustration. When we study generic packages in part 2 of this tutorial, we will see a much better way to define the stack so that it can be used with additional types. Chapter 31 of part 2 of this tutorial includes this same program rewritten as a generic package which can be used with virtually any data type. You should compile this file in preparation for using it in conjunction with the next example program. HOW DO WE USE THE CHARACTER STACK? _________________________________________________________________ The example program TRYSTAK.ADA uses the =============== character stack included in the last program. TRYSTAK.ADA Notice the with and the use clause in lines 4 =============== and 5. These tell the system to get a copy of CharStak, and make it available for use in this program. Two string constants are defined for use later, and two procedures are defined to fill the stack, or add a string of characters to the stack one at a time, and to empty it a character at a time. The main program displays each of the string constants on the monitor, then uses the two procedures to reverse the string of characters and output the reversed strings on the monitor. You should study the program until you understand how it works, even though the program itself is not nearly as important to understand as the concept of the separately compiled package. Be sure to compile and run TRYSTAK.ADA to see that it really does what you expect it to do. THE DYNAMIC STRING PACKAGE _________________________________________________________________ The next example program, named DYNSTRNG.ADA, ================ fulfills a promise made when we were studying DYNSTRNG.ADA strings. At that time, we mentioned that Ada ================ did not have a dynamic string capability. This package adds dynamic strings to Ada to make them much easier to use, and much more flexible. This package, although implementing a complete version of a dynamic string package, is not submitted as the final word in string packages. In fact, it has a problem which we will describe later in this chapter. One construct is used which we have not yet studied in this tutorial although we did mention it in passing in the last chapter. Page 16-2 Chapter 16 - Example Programs Line 33 contains an unconstrained array type declaration. Its use is illustrated in lines 11 and 12 of the program named TRYSTRNG.ADA. This will be studied in part 2 of this tutorial. Other than this one construct, DYNSTRNG.ADA uses no portion of Ada that we have not yet studied in this tutorial, so it does not take advantage of the advanced constructs of Ada. It is meant to be a teaching aid only, but you could use it in a production program, which you are welcome to do as a registered customer of Coronado Enterprises. When you purchased this tutorial, you purchased the right to use any of the included software for whatever purpose you deem necessary, except commercialization of the tutorial itself. You may need to modify it slightly for your own purposes, and you have permission to do so. The dynamic string, as defined here, has a maximum length of 255 characters, with the dynamic length stored in the first element of the string which has a subscript of zero. The string must therefore be declared as a CHARACTER string with a lower bound of 0, and an upper bound representing the maximum length that the string will ever be asked to store. This definition comes from Borland International's implementation of Pascal, which they market as TURBO Pascal. THE DYNSTRNG SPECIFICATION _________________________________________________________________ The specification package of DynStrng is defined in lines 29 through 116 of the file and the comments are complete, giving a thorough definition of the package, and describing how to use it. The body is given in lines 124 through 384, and give the actual implementation. Note that some software developers give you only the specification part of the package, which is all you really need to use it, and hide the body from you. If they provide the compiled body, and the specification source, you have all you need to use the package with that specific compiler. Your compiler came with the package Text_IO, a standard package, and your compiler writer almost certainly did not provide you with the source code to the body, and probably did not give you the source code to the specification in a file, but only on the printed page. The Text_IO package, as defined in the LRM, is only the specification part of the package Text_IO. It can be found in section 14.3.10 of the LRM. You should take notice of the fact that we are overloading the name Put on line 36 of this package so we can use it to output a dynamic string to the monitor. The system knows which one we wish to use by the type of the actual parameter used. The careful observer will notice that we use the Text_IO version of Put in line 132 of the procedure used to overload the name Put. Continuing the discussion of overloading, you will see that we define two procedures with the same name in lines 60 and 63, once again depending on the types to select the proper procedure for each call. Page 16-3 Chapter 16 - Example Programs Study the DynStrng package until you feel you understand it fairly well, then compile the file to prepare for the next program. USING DYNAMIC STRINGS _________________________________________________________________ The example program TRYSTRNG.ADA is designed to ================ use the dynamic string package in various ways TRYSTRNG.ADA by defining strings, inserting characters or ================ strings, deleting portions of strings, and displaying the results. This program was written to test the DynStrng package so it does a lot of silly things. There is nothing new or innovative in this utilitarian program, so you will be left on your own to understand, compile, and execute it. A PROBLEM WITH DYNSTRNG.ADA _________________________________________________________________ The DynStrng package works just fine the way it is used in the TryStrng package, but a problem appears when it is used to copy a string constant into a dynamic string. The problem is due to overloading the name Copy in lines 60 and 63 of the DynStrng specification, and is best illustrated with an example. Consider the following line of Ada code; Copy("Line of text.",Stuff,Result); In this case, the compiler finds that the string constant could be of type STRING or of type DYNAMIC_STRING, and does not know which overloading to use, so it gives a compile error saying that it cannot resolve the type. The way to use this package to do this would be to tell the compiler which one to use by qualifying the string constant as shown in this line of code. Copy(STRING'("Line of text."),Stuff,Result); This will completely resolve the ambiguity and the program will then compile and execute properly. You should include these two lines in a test program to see for yourself that this does resolve the ambiguity. NOW TO FIX THE PROBLEM _________________________________________________________________ There is an excellent solution to this problem that will render this dynamic string package flexible and useful but it requires the use of a discriminated record which we have not yet studied in this tutorial. In part 2 of this tutorial, we will revisit this dynamic string package and offer a much more flexible package for your information and use. Page 16-4 Chapter 16 - Example Programs HOW OLD ARE YOU IN DAYS? _________________________________________________________________ The example program named AGE.ADA, is a silly =============== little program, but intended to illustrate how AGE.ADA to effectively use the keyboard for input to a =============== program. This program will ask you for today's date, and your birthday, then calculate your age in days. There is no provision for leap year, or even for months with other than 31 days. It is intended to illustrate how to put together an interactive program that could be useful in some way. Once again, since we have not studied the advanced topics of Ada yet, we have a limited number of constructs to use. The example programs at the end of Part 2 of this tutorial repeats this program, but uses the predefined Ada package Calendar to get today's date rather than asking the user to supply it. The advanced topics will add flexibility to your use of Ada. Compile and run this program to get a feel for how to write an interactive program. PROGRAMMING EXERCISES _________________________________________________________________ 1. Add an additional function to CHARSTAK.ADA to return a value indicating how many more characters can be pushed onto the stack. 2. Use the new function in TRYSTAK.ADA to output a message to the monitor indicating the amount of space remaining on the stack at the end of the Fill_The_Stack procedure. 3. A MAJOR PROGRAMMING ASSIGNMENT The best way to learn Ada is to use it, so the following programming suggestion is given. After studying the package DYNSTRNG.ADA, put it away and attempt to duplicate it from scratch. You will find that you will use nearly every topic covered in part 1 of this tutorial, and if you get completely stumped, you will have the supplied version of the package to help you over the rough spots. Your goal should be to duplicate the supplied package so closely that the existing program named TRYSTRNG.ADA can use your new version. If you find DYNSTRNG.ADA too big for a first step, you may wish to try to duplicate CHARSTAK.ADA in the same manner before jumping into the dynamic string effort. Page 16-5